﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Collections.Specialized;
using SocialNetwork.Models;
using SocialNetwork;

public class aMembershipProvider : MembershipProvider
{
    #region Fields

    private string _ApplicationName;
    private bool _EnablePasswordReset;
    private bool _EnablePasswordRetrieval = false;
    private bool _RequiresQuestionAndAnswer = false;
    private bool _RequiresUniqueEmail = true;
    private int _MaxInvalidPasswordAttempts;
    private int _PasswordAttemptWindow;
    private int _MinRequiredPasswordLength;
    private int _MinRequiredNonalphanumericCharacters;
    private string _PasswordStrengthRegularExpression;
    private MembershipPasswordFormat _PasswordFormat = MembershipPasswordFormat.Hashed;

    private UserRepository _repository;
    private FBEntities _feedback;

    #endregion

    #region Properties
    
    private UserRepository repository
    {
        get
        {
            if (_repository == null)
                _repository = new UserRepository();
            return _repository;
        }
    }

    private FBEntities feedback
    {
        get
        {
            if (feedback == null)
                _feedback = new FBEntities();
            return feedback;
        }
    }

    public override string ApplicationName
    {
        get { return _ApplicationName; }
        set { _ApplicationName = value; }
    }

    public override bool EnablePasswordReset
    {
        get { return _EnablePasswordReset; }
    }

    public override bool EnablePasswordRetrieval
    {
        get { return _EnablePasswordRetrieval; }
    }

    public override bool RequiresQuestionAndAnswer
    {
        get { return _RequiresQuestionAndAnswer; }
    }

    public override bool RequiresUniqueEmail
    {
        get { return _RequiresUniqueEmail; }
    }

    public override int MaxInvalidPasswordAttempts
    {
        get { return _MaxInvalidPasswordAttempts; }
    }
    public override int PasswordAttemptWindow
    {
        get { return _PasswordAttemptWindow; }
    }

    public override int MinRequiredPasswordLength
    {
        get { return _MinRequiredPasswordLength; }
    }

    public override int MinRequiredNonAlphanumericCharacters
    {
        get { return _MinRequiredNonalphanumericCharacters; }
    }

    public override string PasswordStrengthRegularExpression
    {
        get { return _PasswordStrengthRegularExpression; }
    }

    public override MembershipPasswordFormat PasswordFormat
    {
        get { return _PasswordFormat; }
    }

    #endregion



    #region Init
    
    public override void Initialize(string name, NameValueCollection config)
    {
        if (config == null)
            throw new ArgumentNullException("config");

        if (name == null || name.Length == 0)
            name = "CustomMembershipProvider";

        if (String.IsNullOrEmpty(config["description"]))
        {
            config.Remove("description");
            config.Add("description", "Custom Membership Provider");
        }

        base.Initialize(name, config);

        _ApplicationName = GetConfigValue(config["applicationName"],
               System.Web.Hosting.HostingEnvironment.ApplicationVirtualPath);
        _MaxInvalidPasswordAttempts = Convert.ToInt32(
                      GetConfigValue(config["maxInvalidPasswordAttempts"], "5"));
        _PasswordAttemptWindow = Convert.ToInt32(
                      GetConfigValue(config["passwordAttemptWindow"], "10"));
        _MinRequiredNonalphanumericCharacters = Convert.ToInt32(
                      GetConfigValue(config["minRequiredNonalphanumericCharacters"], "1"));
        _MinRequiredPasswordLength = Convert.ToInt32(
                      GetConfigValue(config["minRequiredPasswordLength"], "6"));
        _EnablePasswordReset = Convert.ToBoolean(
                      GetConfigValue(config["enablePasswordReset"], "true"));
        _PasswordStrengthRegularExpression = Convert.ToString(
                       GetConfigValue(config["passwordStrengthRegularExpression"], @"^([a-z]+[A-Z]+\d+[!@#\$%\^\*\(\)]+){6,12}$"));
    }

    private string GetConfigValue(string configValue, string defaultValue)
    {
        return (string.IsNullOrEmpty(configValue)) ? defaultValue : configValue;
    }
    
    #endregion

    #region METHODS

    public bool ValidateUsername(string username)// if username exists it returns TRUE
    {
        return repository.ValidateUsername(username);
    }

    public override bool ValidateUser(string username, string password)
    {
        if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password))
            return false;

        var hashed = FormsAuthentication.HashPasswordForStoringInConfigFile(password, "md5");
        var exists = repository.GetAllUsers().Any(x => x.Username == username && x.Password == hashed);
        return exists;
    }

    public override bool ChangePassword(string username, string oldPassword, string newPassword)
    {
        if (!ValidateUser(username, oldPassword) || string.IsNullOrEmpty(newPassword))
            return false;

        var hashed = FormsAuthentication.HashPasswordForStoringInConfigFile(newPassword, "md5");
        return repository.ChangePassword(username, hashed);
    }

    public IEnumerable<User> GetUsersByCondition(Func<User, bool> predicate, Func<User, object> orderby)
    {
        return repository.GetUsersByCondition(predicate, orderby);
    }

    public bool CreateUser(RegisterModel user, string roleName)
    {
        return repository.CreateUser(user, roleName);
    }

    public bool SendFeedback(FeedbackModel feedbackModel)
    {
        try
        {
            FeedbackData feedbackData = new FeedbackData()
                                        {
                                            Subject = feedbackModel.Subject,
                                            Message = feedbackModel.Message
                                        };
            feedback.AddToFeedbackData(feedbackData);
        }
        catch (Exception)
        {
            return false;
        }

        return true;
    }

    public bool UpdateUser(User user)
    {
        return true;
    }


    public override bool DeleteUser(string username, bool deleteAllRelatedData = true)
    {
        return repository.DeleteUser(username);
    }

    public bool DeleteUser(Guid id)
    {
        return repository.DeleteUser(id);
    }

    public IEnumerable<User> GetAllUsers()
    {
        return repository.GetAllUsers();
    }

    public User GetUser(Guid id)
    {
        return repository.GetUser(id);
    }

    #endregion




    #region NotImplemented

    public override MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize, out int totalRecords)
    {
        throw new NotImplementedException();
    }

    public override MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize, out int totalRecords)
    {
        throw new NotImplementedException();
    }

    public override MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords)
    {
        throw new NotImplementedException();
    }

    public override int GetNumberOfUsersOnline()
    {
        return repository.GetAllUsers().Where(user => user.IsOnline == true).Count();
    }

    public override string GetPassword(string username, string answer)
    {
        throw new NotImplementedException();
    }

    public override MembershipUser GetUser(string username, bool userIsOnline)
    {
        throw new NotImplementedException();
    }

    public override MembershipUser GetUser(object providerUserKey, bool userIsOnline)
    {
        throw new NotImplementedException();
    }

    public override string GetUserNameByEmail(string email)
    {
        throw new NotImplementedException();
    }

    public override string ResetPassword(string username, string answer)
    {
        throw new NotImplementedException();
    }

    public override bool UnlockUser(string userName)
    {
        throw new NotImplementedException();
    }

    public override void UpdateUser(MembershipUser user)
    {
        throw new NotImplementedException();
    }

    public override MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status)
    {
        throw new NotImplementedException();
    }

    public override bool ChangePasswordQuestionAndAnswer(string username, string password, string newPasswordQuestion, string newPasswordAnswer)
    {
        return false;
    }

    #endregion
}